package io.zhiller.simpletemplate.plugin.update

import android.content.Context
import android.util.Log
import java.io.File







/**
 * 密封类Version表示一个版本号，包含主版本号、次版本号、修订号和构建号。
 * Version类实现了Comparable接口，以允许版本号之间的比较。
 * 版本号的各个部分乘以相应的权重，以确保在比较时主版本号具有最高优先级，其次是次版本号、修订号和构建号。
 */
sealed class BuildVersion(
  val major: Int, val minor: Int, val patch: Int, val build: Int = 0
) : Comparable<BuildVersion> {
  companion object {
    // 主版本号的权重
    private const val MAJOR = 10_000_000L
    
    // 次版本号的权重
    private const val MINOR = 100_000L
    
    // 修订号的权重
    private const val PATCH = 1000L
    
    // 构建号的权重
    private const val BUILD = 10L
    
    // 稳定版的特殊权重
    private const val STABLE = 100L
  }
  
  /**
   * 抽象函数toVersionString返回版本号的字符串表示形式。
   * 具体的实现将在子类中提供。
   */
  abstract fun toVersionString(): String
  
  /**
   * 抽象函数toVersionNumber返回版本号的数值表示形式。
   * 具体的实现将在子类中提供。
   */
  abstract fun toVersionNumber(): Long
  
  /**
   * 比较两个版本号。
   * 通过比较它们的数值表示形式来确定版本号的顺序。
   */
  override fun compareTo(other: BuildVersion): Int {
    return this.toVersionNumber().compareTo(other.toVersionNumber())
  }
  
  /**
   * Stable类表示一个稳定版的版本号。
   */
  class Stable(major: Int, minor: Int, patch: Int) : BuildVersion(major, minor, patch) {
    /**
     * 生成稳定版版本号的字符串表示形式。
     * 格式为主版本号.次版本号.修订号。
     */
    override fun toVersionString(): String {
      return "$major.$minor.$patch"
    }
    
    /**
     * 生成稳定版版本号的数值表示形式。
     * 通过将各个部分乘以相应的权重并相加，再加上稳定版的特殊权重，来计算数值表示。
     */
    override fun toVersionNumber(): Long =
      (major * MAJOR) + (minor * MINOR) + (patch * PATCH) + STABLE
  }
  
  /**
   * Beta类表示一个测试版的版本号。
   */
  class Beta(major: Int, minor: Int, patch: Int, build: Int) :
    BuildVersion(major, minor, patch, build) {
    /**
     * 生成测试版版本号的字符串表示形式。
     * 格式为主版本号.次版本号.修订号-beta构建号。
     */
    override fun toVersionString(): String {
      return "$major.$minor.$patch-beta$build"
    }
    
    /**
     * 生成测试版版本号的数值表示形式。
     * 通过将各个部分乘以相应的权重并相加，来计算数值表示。
     */
    override fun toVersionNumber(): Long =
      (major * MAJOR) + (minor * MINOR) + (patch * PATCH) + (build * BUILD)
  }
}

/**
 * 将字符串转换为版本号对象
 * 该函数旨在处理符合特定格式的版本号字符串，如"v1.2.3"或"v1.2.3-beta4"
 * 它会移除前缀'v'（如果存在），并解析主要版本号、次要版本号、修订号和构建号（如果存在）
 * 如果版本号中包含"beta"，则将其视为测试版，否则视为稳定版
 *
 * @return 返回一个Version对象，表示解析后的版本号如果解析失败或格式不正确，将记录错误日志
 */
fun String.toVersion(): BuildVersion {
  // 移除版本号前缀'v'，如果存在
  this.replace("v", "").run {
    // 定义一个正则表达式来匹配版本号格式，包括可选的预发布版本标识（如alpha或beta）和构建号
    val regex = Regex("""(\d+)\.(\d+)\.(\d+)(?:-(?:alpha|beta)?(\d+))?""")
    // 使用正则表达式匹配整个字符串
    val matchResult = regex.matchEntire(this)
    
    // 解构匹配结果，提取主要版本号、次要版本号、修订号和构建号（如果存在）
    val (major, minor, patch, build) = matchResult!!.destructured
    // 尝试将版本号组件转换为整数，如果失败则记录错误日志
    try {
      major.toInt()
      minor.toInt()
      patch.toInt()
    } catch (e: Exception) {
      Log.e("UpdateUtil", "Failed to parse version name: $this")
    }
    // 根据版本号字符串是否包含"beta"，返回相应的Version对象
    return if (this.contains("beta")) {
      BuildVersion.Beta(major.toInt(), minor.toInt(), patch.toInt(), build.toInt())
    } else {
      BuildVersion.Stable(major.toInt(), minor.toInt(), patch.toInt())
    }
  }
}

